﻿package rd.hardcore.ui 
{
	import aze.motion.eaze;
	import caurina.transitions.Tweener;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Graphics;
	import flash.display.Shader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BlurFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.SoundMixer;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	import rd.hardcore.events.EqDataEvent;
	import rd.hardcore.events.SoundSystemEvent;
	import rd.hardcore.params.GlobalParams;
	
	/**
	 * ...
	 * @author Thibault Perret
	 */
	public class EqVisualization extends Sprite
	{
		private const PLOT_HEIGHT : int = 195;
		private const CHANNEL_LENGTH:int = 80;
		
		private var ba:ByteArray;
		private var sp:Sprite;
		private var g:Graphics;
		private var bmpD:BitmapData;
		private var toBlur:Sprite;
		
		private var soundPlay	: Boolean = false;
		private var isLiving	: Boolean = false;
		private var endTimer 	: Timer;
		private var bmp			: Bitmap;
		private var secondColor	: uint;
		private var fisrtColor	: uint;
		private var toBlurPosX	: int = 0;
		
		private var centerPosX	: int = 0;
		private var centerPosY	: int = 0;
		private var bmpMask		: Sprite;
		
		//private var debugSp:Sprite = new Sprite();
		//private var GG:Graphics;
		
		public function EqVisualization() 
		{
			mouseChildren = false;
			mouseEnabled = false;

			if (stage)
				init(null);
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			//addEventListener(Event.REMOVED_FROM_STAGE, dispose);
			
			ba = new ByteArray();
			
			sp = new Sprite();
			
			g = sp.graphics;
			
			bmpD = new BitmapData(400, 400, true, 0x00000000);
			bmp = new Bitmap(bmpD);
			
			x = ((GlobalParams.WIDTH - 760 ) >> 1);
			
			endTimer = new Timer(1500);
			
			var filtreTV:Shape = new Shape();
			filtreTV.graphics.beginBitmapFill(makeTexture());
			filtreTV.graphics.drawRoundRect(0, 20, 760, 310,13,13);
			filtreTV.graphics.endFill();
			addChild(filtreTV);
			filtreTV.blendMode = BlendMode.OVERLAY;
		}
		
		private function makeTexture() : BitmapData
		{
			var bmd : BitmapData = new BitmapData(2, 2, true,0x353535);
			bmd.setPixel32(1, 0, 0x33000000);
			bmd.setPixel32(0, 1, 0x33000000);
			return bmd;
		}
		
		public function pixelize():void
		{
			if (!isLiving) {
				toBlur = new Sprite();
				addChildAt(toBlur,0);
			}
			
			
			centerPosX = 50 + Math.random() * 610;
			centerPosY = 50 + Math.random() * 240;
			
			addEventListener(Event.ENTER_FRAME, loop);
			soundPlay = true;
			fisrtColor = Math.random() * 0xffffff;
			secondColor = Math.random() * 0xffffff;
			
			Tweener.addTween(toBlur, { alpha:1, time:1} );

			toBlur.x = toBlurPosX;
			toBlur.y = 0;//+ Math.random() * GlobalParams.HEIGHT;
			
			endTimer.removeEventListener(TimerEvent.TIMER, handleendTimer);
			endTimer.stop();
			bmpD = null;

			bmpD = new BitmapData(760, 310, true, 0x00000000);
			bmp = new Bitmap(bmpD);
			bmp.y = 20;
		}
		
		public function stopPixelize(e:SoundSystemEvent):void
		{
			soundPlay = false;
			endTimer.addEventListener(TimerEvent.TIMER, handleendTimer);
			endTimer.start();
		}
		
		private function handleendTimer(e:TimerEvent):void 
		{
			endTimer.removeEventListener(TimerEvent.TIMER, handleendTimer);
			endTimer.stop();
			removeEventListener(Event.ENTER_FRAME, loop);
			Tweener.addTween(toBlur, { alpha:0, time:3, onComplete:cleanBlur, transition:"linear" } );
			isLiving = false;
		}
		
		private function cleanBlur():void
		{

			if (!isLiving)
			{
				var b : Bitmap;
				while (toBlur.numChildren > 0)
				{
					b = (toBlur.removeChildAt(0) as Bitmap);
					b.bitmapData.dispose();
					b = null;
				}
				if (toBlur) {
					removeChild(toBlur);
					toBlur = null;
				}
			}
			
		}
		
		private function loop(e:Event):void 
		{
			isLiving = true;
			
			var pt:Point = new Point(0, 0);
			var rect:Rectangle = new Rectangle(0, 0, bmpD.width, bmpD.height);
			var filter:BlurFilter = new BlurFilter(2, 2, BitmapFilterQuality.MEDIUM);
			bmpD.applyFilter(bmpD, rect, pt, filter);
			toBlur.addChild(bmp);
			//toBlur.blendMode = BlendMode.OVERLAY;
			
			if (soundPlay){
				SoundMixer.computeSpectrum(ba, true);
				g.clear();
				
				var n:Number = 0;
				var angle:Number;
				var rayon:Number;
				
				g.beginFill(fisrtColor, .1);
				for (var i:int = 0; i < CHANNEL_LENGTH; i++) {
					n = (ba.readFloat() * PLOT_HEIGHT);
					angle = (2 * Math.PI * i) / CHANNEL_LENGTH;
					rayon =  (n * .1);
					g.drawCircle(centerPosX + rayon * Math.cos(angle), centerPosY + rayon * Math.sin(angle), n * .3);
					
					if (i == 5) {
						dispatchEvent(new EqDataEvent(EqDataEvent.BOUCING_BASS_LEVEL, n, true));
					}
					/*	Version étalée	*/
					//g.drawCircle(centerPosX + rayon - rayon*Math.cos(angle), centerPosY + rayon - rayon*Math.sin(angle), n*.3);
					

					
				}
				//g.endFill();
				
				g.beginFill(secondColor, .8);
				for (i = CHANNEL_LENGTH; i > 0; i--) {
					angle = (2 * Math.PI * i) / CHANNEL_LENGTH;
					rayon =  (20 + n);
					n = (ba.readFloat() * PLOT_HEIGHT);
					g.drawCircle(centerPosX + 50 + rayon * Math.cos(angle), centerPosY + 50 + rayon * Math.sin(angle), n * .3);
					
					/*	Version étalée	*/
					//g.drawCircle(centerPosX + 50+rayon - rayon*Math.cos(angle), centerPosY + 50+ rayon - rayon*Math.sin(angle), n*.3);
					
				}
				g.endFill();
			}
			
			var mtr:Matrix = new Matrix();
			mtr.translate( 50, 50 );
			bmpD.draw(sp, mtr, null, BlendMode.ADD);
		}

		
	}

}